<template>
  <terminal
    :name="name"
    context="Root"
    :theme="theme"
    :line-space="10"
    cursor-style="bar"
    @exec-cmd="command"
    :enable-input-tips="false"
    :enable-help-box="false"
    :show-header="false"
    :auto-help="false"
    :init-log="null"
  />
</template>

<script setup lang="ts">
import ansiToHtml from "ansi-to-html";
import { installCmdList } from "../config";
import { VoidTypeFun } from "../../../interface";
import { TerminalFlash } from "vue-web-terminal";
import dark from "../../../style/theme/dark.css?inline";
import light from "../../../style/theme/light.css?inline";
import { configTheme, TerminalApi } from "vue-web-terminal";
import WebContainerAPI from "../../../class/WebContainerAPI";

configTheme("light", light);
configTheme("dark", dark);

import { ref } from "vue";

const theme = ref("light");

const { name } = defineProps<{ name: string }>();

const flash = new TerminalFlash();
const convert = new ansiToHtml();
/**
 * 即使是多终端，也是由该组件统一派发的事件，并且只是name属性不同，因此，直接在该组件内执行 command 是最合适的
 *  1. 终端输入的命令，需要直接传递到 pinia web container 中执行
 */
function command(
  _cmdKey: string,
  command: string,
  success: VoidTypeFun<TerminalFlash | { content: string }>,
  failed: VoidTypeFun<TerminalFlash | { content: string }>,
  name: string
) {
  console.log("终端", name, "，执行command:", command);
  // 特殊的命令需要单独处理
  if (installCmdList.includes(command)) {
    // 执行下载依赖，应该用回显模式
    success(flash);
    WebContainerAPI.execTerminal(command, (content: string | Uint8Array) => {
      try {
        if (content instanceof Uint8Array) {
          // 如果是二进制数据，先解码
          const decoder = new TextDecoder();
          content = decoder.decode(content);
        }

        // 将 ANSI 转换为 HTML
        const htmlContent = convert.toHtml(content);

        success({ content: htmlContent });
      } catch (error) {
        failed({ content: String(error) });
      }
    });
  } else if (command === "cls") {
    // 模拟 cls 命令 - 真正执行的是clear 命令，清空 终端
    TerminalApi.clearLog(name);
    // 任何终端操作，都必须显示调用 success 或者 failed，才会进入下一次回显
    success({ content: "" });
  } else {
    WebContainerAPI.execTerminal(command, (content) => {
      try {
        if (content instanceof Uint8Array) {
          // 如果是二进制数据，先解码
          const decoder = new TextDecoder();
          content = decoder.decode(content);
        }
        // 将 ANSI 转换为 HTML
        const htmlContent = convert.toHtml(content);
        success({ content: htmlContent });
      } catch (error) {
        failed({ content: String(error) });
      }
    });
  }
}
</script>

<style lang="css" scoped>
.t-container {
  box-shadow: none !important;
}
</style>
